/*
 * Column.java
 *
 * Copyright (c) 2008 Teamnet. All Rights Reserved.
 *
 * This source file may not be copied, modified or redistributed,
 * in whole or in part, in any form or for any reason, without the express
 * written consent of Teamnet.
 */
package ro.prjmanager.database.model;

import ro.prjmanager.constants.BackendConstants;

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * This class maps an database column
 */
public class Column {
    //hold the datbase column name
    private String databaseColumnName;
    //hold the java column name
    private String javaColumnName;
    //hold the coresponding Java type
    private String javaType;
    //hold the coresponding Database type
    private String databaseType;
    //hold the column index from the table
    private int idx;
    //true if this column is primary key
    private boolean primaryKey;
    //true if this columns is foreign key
    private boolean foreignKey;
    //this attribute hold the nullable propertye of this column
    private boolean nullable;
    //the table that hold this column
    private Table ownerTable;
    //hold the refered column
    private Column foreingColumn;
    //hold the foreing key columns that refer this primary key
    //if this attribute is not null than this column is an primary key
    private List<Column> relationColumns;
    //hold the column size in byte
    private int columnSize;
    private boolean isLob;
    


    /**
     * This is the default constructor
     */
    public Column() {

    }


    public String getDatabaseColumnName() {
        return databaseColumnName;
    }

    public void setDatabaseColumnName(String databaseColumnName) {
        this.databaseColumnName = databaseColumnName;
    }

    public String getJavaColumnName() {
        return javaColumnName;
    }

    public void setJavaColumnName(String javaColumnName) {
        this.javaColumnName = javaColumnName;
    }

    public String getJavaType() {
        return javaType;
    }

    public void setJavaType(String javaType) {
        this.javaType = javaType;
    }

    public String getDatabaseType() {
        return databaseType;
    }

    public void setDatabaseType(String databaseType) {
        this.databaseType = databaseType;
    }

    public int getIdx() {
        return idx;
    }

    public void setIdx(int idx) {
        this.idx = idx;
    }

    public boolean isPrimaryKey() {
        return primaryKey;
    }

    public void setPrimaryKey(boolean primaryKey) {
        this.primaryKey = primaryKey;
    }

    public Column getForeingColumn() {
        return foreingColumn;
    }

    public void setForeingColumn(Column foreingColumn) {
        this.foreingColumn = foreingColumn;
    }

    public Table getOwnerTable() {
        return ownerTable;
    }

    public void setOwnerTable(Table ownerTable) {
        this.ownerTable = ownerTable;
    }

    public boolean isNullable() {
        return nullable;
    }

    public void setNullable(boolean nullable) {
        this.nullable = nullable;
    }

    public boolean isForeignKey() {
        return foreignKey;
    }

    public void setForeignKey(boolean foreignKey) {
        this.foreignKey = foreignKey;
    }

    public int getColumnSize() {
        return columnSize;
    }

    public void setColumnSize(int columnSize) {
        this.columnSize = columnSize;
    }

    public List<Column> getRelationColumns() {
        return relationColumns;
    }

    public void setRelationColumns(List<Column> relationColumns) {
        this.relationColumns = relationColumns;
    }

    /**
     * This method is an delegate over the relationColumns
     * and add an relation column to the list of the relations
     * @param relationalColumn - the relational column
     * @return - true if the opperation has been successfully
     */
    public boolean add(Column relationalColumn) {
        if(relationColumns==null)
            relationColumns=new ArrayList<Column>();
        return relationColumns.add(relationalColumn);
    }

    /**
     * This method merge the properties of an givven Column object over the
     * properties of the current object
     * @param col - The givven Column object
     */
    public void merge(Column col) {

        if (databaseColumnName == null)
            databaseColumnName = col.databaseColumnName;
        if (javaColumnName == null)
            javaColumnName = col.javaColumnName;
        if (javaType == null)
            javaType = col.javaType;
        if (databaseType == null)
            databaseType = col.databaseType;
        if (idx == 0)
            idx = col.idx;
        if (!primaryKey)
            primaryKey = col.primaryKey;
        if (!foreignKey)
            foreignKey = col.foreignKey;
        if (!nullable)
            nullable = col.nullable;
        if (ownerTable == null)
            ownerTable = col.ownerTable;
        if (foreingColumn == null)
            foreingColumn = col.foreingColumn;
        if (columnSize == 0)
            columnSize = col.columnSize;
        if(relationColumns==null)
            relationColumns=col.relationColumns;
    }

    /**
     * This method build the coresponding getter name for this column
     * @return - the getter name for the column
     */
    public String getter(){
        return BackendConstants.GET + getJavaColumnName().substring(0,1).toUpperCase()+getJavaColumnName().substring(1);
    }

    /**
     * This method build the coresponding setter name for this column
     * @return - the setter name for the column
     */
    public String setter(){
       return BackendConstants.SET + getJavaColumnName().substring(0,1).toUpperCase()+getJavaColumnName().substring(1);
    }

    /**
     * This method return true if other columns are foreign key to this column
     * @return true if other columns are foreign key to this column
     */
    public boolean hasOtherRelations(){
        return relationColumns!=null&&!relationColumns.isEmpty();
    }


    public String toString() {
        return "Column{" +
                "databaseColumnName='" + databaseColumnName + '\'' +
                ", javaColumnName='" + javaColumnName + '\'' +
                ", javaType='" + javaType + '\'' +
                ", databaseType='" + databaseType + '\'' +
                ", idx=" + idx +
                ", primaryKey=" + primaryKey +
                ", foreignKey=" + foreignKey +
                ", nullable=" + nullable +
                ", foreingColumn=" + foreingColumn +
                ", columnSize=" + columnSize +(relationColumns==null||relationColumns.isEmpty()?"":
                ", relationColumns="+ Arrays.toString(relationColumns.toArray()) )+
                '}';
    }

    public boolean isLob() {
        return databaseType.equals("BLOB")||databaseType.equals("CLOB");
    }

    public void setLob(boolean lob) {
        isLob = lob;
    }

    public static void main(String[] args) {
        Column col=new Column();
        col.setDatabaseColumnName("ID_USERS");
        System.out.println(col.getter());

    }
}
